package comjj.pool;

import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class GenericConnectionPool implements InitializingBean,
		DisposableBean {
	private static final Logger logger = LoggerFactory
			.getLogger(GenericConnectionPool.class);
	/** 可以从缓存池中分配对象的最大数量 */
	private int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE;
	/** 缓存池中最大空闲对象数量 */
	private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;
	/** 缓存池中最小空闲对象数量 */
	private int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE;
	/** 阻塞的最大数量 */
	private long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT;
	/** 从缓存池中分配对象，是否执行PoolableObjectFactory.validateObject方法 */
	private boolean testOnBorrow = GenericObjectPool.DEFAULT_TEST_ON_BORROW;
	private boolean testOnReturn = GenericObjectPool.DEFAULT_TEST_ON_RETURN;
	private boolean testWhileIdle = GenericObjectPool.DEFAULT_TEST_WHILE_IDLE;
	/** 对象缓存池 */
	protected ObjectPool objectPool = null;

	private PoolableObjectFactory poolableObjectFactory;

	/**
     * 
     */
	@Override
	public void afterPropertiesSet() throws Exception {
		if (poolableObjectFactory == null)
			throw new Exception("poolableObjectFactory can not be not");
		// 对象池
		objectPool = new GenericObjectPool();
		//
		((GenericObjectPool) objectPool).setMaxActive(maxActive);
		((GenericObjectPool) objectPool).setMaxIdle(maxIdle);
		((GenericObjectPool) objectPool).setMinIdle(minIdle);
		((GenericObjectPool) objectPool).setMaxWait(maxWait);
		((GenericObjectPool) objectPool).setTestOnBorrow(testOnBorrow);
		((GenericObjectPool) objectPool).setTestOnReturn(testOnReturn);
		((GenericObjectPool) objectPool).setTestWhileIdle(testWhileIdle);
		((GenericObjectPool) objectPool)
				.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
		// 设置factory
		objectPool.setFactory(poolableObjectFactory);
	}
	

	@Override
	public void destroy() {
		try {
			objectPool.close();
		} catch (Exception e) {
			throw new RuntimeException("erorr destroy()", e);
		}
	}

	public int getMaxActive() {
		return maxActive;
	}

	public void setMaxActive(int maxActive) {
		this.maxActive = maxActive;
	}

	public int getMaxIdle() {
		return maxIdle;
	}

	public void setMaxIdle(int maxIdle) {
		this.maxIdle = maxIdle;
	}

	public int getMinIdle() {
		return minIdle;
	}

	public void setMinIdle(int minIdle) {
		this.minIdle = minIdle;
	}

	public long getMaxWait() {
		return maxWait;
	}

	public void setMaxWait(long maxWait) {
		this.maxWait = maxWait;
	}

	public boolean isTestOnBorrow() {
		return testOnBorrow;
	}

	public void setTestOnBorrow(boolean testOnBorrow) {
		this.testOnBorrow = testOnBorrow;
	}

	public boolean isTestOnReturn() {
		return testOnReturn;
	}

	public void setTestOnReturn(boolean testOnReturn) {
		this.testOnReturn = testOnReturn;
	}

	public boolean isTestWhileIdle() {
		return testWhileIdle;
	}

	public void setTestWhileIdle(boolean testWhileIdle) {
		this.testWhileIdle = testWhileIdle;
	}

	public ObjectPool getObjectPool() {
		return objectPool;
	}

	public void setObjectPool(ObjectPool objectPool) {
		this.objectPool = objectPool;
	}

	public PoolableObjectFactory getPoolableObjectFactory() {
		return poolableObjectFactory;
	}

	public void setPoolableObjectFactory(
			PoolableObjectFactory poolableObjectFactory) {
		this.poolableObjectFactory = poolableObjectFactory;
	}

}